<template>
    <div class="flex flex-1 flex-col overflow-hidden">
        <div v-if="step === 0" class="p-4 enter-from-box">
            <el-form label-width="70px" label-position="left">
                <el-form-item label="网页链接:" prop="intro">
                    <div class="w-[700px]">
                        <el-input
                            v-model="webUrls"
                            type="textarea"
                            placeholder="仅支持静态链接，每行一个，最多 10 个网址（以http或https开头）"
                            :rows="10"
                            resize="none"
                        />
                    </div>
                </el-form-item>
                <el-form-item >
                    <el-button
                        class="h-[38px]"
                        type="primary"
                        :disabled="!webUrls"
                        @click="handleNext(1)"
                    >下一步</el-button>
                </el-form-item>
            </el-form>
        </div>

        <template v-if="step === 1">
            <div class="flex h-full overflow-hidden">
                <!-- 左侧 -->
                <div class="min-w-[540px] border-r border-br-extra-light">
                    <el-scrollbar>
                        <div class="p-4">
                            <!-- 规则配置 -->
                            <div class="segment-type-box">
                                <h5 class="mb-2 text-base text-tx-regular">训练模式:</h5>
                                <div class="flex items-center">
                                    <div class="segment mr-4" @click="formData.train_mode === 'chunk'">
                                        <el-radio v-model="formData.train_mode" value="chunk" size="large">
                                            <div class="flex items-center">
                                                <span class="mr-2">直接分段</span>
                                                <el-popover
                                                    placement="bottom"
                                                    effect="dark"
                                                    trigger="hover"
                                                    :width="300"
                                                    content="将文本按规则分段处理后，将段落内容转换为支持语义检索的格式，适合大多数场景。"
                                                >
                                                    <template #reference>
                                                        <icon name="svg-icon-Question" />
                                                    </template>
                                                </el-popover>
                                            </div>
                                        </el-radio>
                                    </div>
                                    <div class="segment" @click="formData.train_mode === 'qa'">
                                        <el-radio v-model="formData.train_mode" value="qa" size="large">
                                            <div class="flex items-center">
                                                <span class="mr-2">问答拆分</span>
                                                <el-popover
                                                    placement="bottom"
                                                    effect="dark"
                                                    trigger="hover"
                                                    :width="300"
                                                    content="基于规则的分段策略，将原始文本划分为较大段落单元，
                                                    并调用AI为每个段落生成精准的问答对。这种方法在确保高检索精度的同时，
                                                    会不可避免地损失部分文本细节信息。"
                                                >
                                                    <template #reference>
                                                        <icon name="svg-icon-Question" />
                                                    </template>
                                                </el-popover>
                                            </div>
                                        </el-radio>
                                    </div>
                                </div>

                                <h5 class="mt-4 mb-2 text-base text-tx-regular">处理方式:</h5>
                                <div class="grid gap-3">
                                    <div
                                        class="segment"
                                        :class="formData.chunk_type === 'automatic' ? 'active' : ''"
                                        @click="formData.chunk_type = 'automatic'"
                                    >
                                        <el-radio v-model="formData.chunk_type" value="automatic" size="large">自动</el-radio>
                                        <p class="ml-5 text-xs text-tx-placeholder">自动设置分割和预处理规则</p>
                                    </div>
                                    <div
                                        class="segment"
                                        :class="formData.chunk_type === 'custom' ? 'active' : ''"
                                        @click="formData.chunk_type = 'custom'"
                                    >
                                        <el-radio v-model="formData.chunk_type" value="custom" size="large">自定义规则</el-radio>
                                        <p class="ml-5 text-xs text-tx-placeholder">自定义设置分制和预处理规则</p>
                                        <div v-if="formData.chunk_type === 'custom'" class="ml-5 mt-4">
                                            <p class="mb-1 text-tx-regular">切割分块长度</p>
                                            <el-input
                                                v-model="formData.chunk_size"
                                                type="number"
                                                :min="chunk_size_range[formData.train_mode]['min']"
                                                :max="chunk_size_range[formData.train_mode]['max']"
                                            />
                                        </div>
                                        <div v-if="formData.chunk_type === 'custom'" class="ml-5 mt-4">
                                            <p class="mb-1 text-tx-regular">切割重叠字符</p>
                                            <el-input v-model="formData.chunk_overlap" type="number" :min="0" :max="1000" />
                                        </div>
                                        <div v-if="formData.chunk_type === 'custom'" class="ml-5 mt-4">
                                            <p class="mb-1 text-tx-regular">自定义分隔符</p>
                                            <el-input v-model="formData.separators" placeholder="==SPLIT=="/>
                                        </div>
                                    </div>
                                </div>
                            </div>

                            <!-- 链接列表 -->
                            <ul v-if="fileLists.length > 0" class="file-list-box">
                                <li
                                    v-for="(item, index) in fileLists"
                                    :key="index"
                                    :class="index === fileIndex ? 'active' : ''"
                                    @click="fileIndex = index"
                                >
                                    <icon name="el-icon-Link" :size="22" color="#409eff"/>
                                    <div class="flex-1 ml-1">
                                        <h3>{{ item.name }}</h3>
                                    </div>
                                    <icon name="el-icon-Delete" :size="16" />
                                </li>
                            </ul>
                        </div>
                    </el-scrollbar>
                </div>

                <!-- 右侧 -->
                <div v-loading="previewLoading" class="flex flex-col flex-1 overflow-hidden">
                    <div class="p-4 text-base font-medium text-tx-regular">
                        分段预览 ({{ fileParse.split_count || 0 }})
                    </div>
                    <div class="flex-1 overflow-hidden">
                        <el-scrollbar>
                            <div class="parse-list-box">
                                <div v-for="(item, index) in fileParse.lists" :key="index" class="parse-box">
                                    <div class="title">
                                        <span class="section">#{{ index + 1 }}</span>
                                        <span class="m-2.5 font-medium text-tx-regular">
                                            {{ fileLists[fileIndex].name }}
                                        </span>
                                    </div>
                                    <div class="content">{{ item.question }}</div>
                                </div>
                            </div>
                        </el-scrollbar>
                    </div>
                </div>
            </div>

            <div class="p-4 pb-2 flex items-center justify-end border-t border-br-extra-light">
                <el-button
                    class="ml-3 h-[38px]"
                    :disabled="fileLists.length <= 0 || loading"
                    @click="resetPreview(fileIndex)"
                >重新预览</el-button>
                <el-button
                    class="ml-3 h-[38px]"
                    type="primary"
                    :disabled="fileLists.length <= 0"
                    :loading="loading"
                    @click="handleSubmit"
                >确定导入</el-button>
            </div>
        </template>
    </div>
</template>

<script setup lang="ts">
import type { UploadUserFile } from 'element-plus'
import knowArchiveApi from '~/api/agent/know/archive'

const emits = defineEmits(['retreat'])
const props = defineProps({
    kb: {
        type: String,
        default: ''
    }
})

const step = ref<number>(0)
const webUrls = ref<string>('')
const fileIndex = ref<number>(-1)
const fileLists = ref<UploadUserFile[]>([])
const fileParse = ref({} as KnowArchiveParseResponse)

// 预览加载
const previewLoading = ref<boolean>(false)

// 切割大小
const chunk_size_range: any = {
    chunk: {default: 512, min: 100, max: 8000},
    qa: {default: 8000, min: 3000, max: 32000}
}

// 表单数据
const loading = ref<boolean>(false)
const formData = reactive({
    kb: props.kb,
    scene: 'link',
    train_mode: 'chunk',
    chunk_type: 'automatic',
    chunk_size: 512,
    chunk_overlap: 0,
    separators: ''
})

/**
 * 下一步
 *
 * @param {number} nextstep
 * @author zero
 */
const handleNext = (nextstep: number) => {
    if (nextstep === 1) {
        let status = true
        const exits: string[] = []
        const urls = webUrls.value.trim().split('\n')
        for (let i = 0; i < urls.length; i++) {
            const url: string = urls[0].trim()
            const urlPattern = /^(https?:\/\/[^\s$.?#].\S*)$/i
            if (!urlPattern.test(url)) {
                status = false
                feedback.msgError('存在不合规的网址: ' + url)
                break
            }
            if (exits.includes(url)) {
                status = false
                feedback.msgError('存在相同的网址: ' + url)
                break
            }
            exits.push(url)
            fileLists.value.push({name: url, url: url, size: 0})
        }
        if (status) {
            step.value = nextstep
            fileIndex.value = 0
        }
    }
}

/**
 * 重新预览
 *
 * @param {number} index
 * @author zero
 */
const resetPreview = async (index: number) => {
    previewLoading.value = true
    const fileUrl = fileLists.value[index].url
    fileParse.value = await knowArchiveApi.parse({
        kb: formData.kb,
        scene: formData.scene,
        chunk_size: formData.chunk_size,
        separators: formData.separators,
        chunk_overlap: formData.chunk_overlap,
        url: String(fileUrl)
    }).finally(() => {
        setTimeout(() => {
            previewLoading.value = false
        }, 1000)
    })
}

/**
 * 提交导入
 *
 * @author zero
 */
const handleSubmit = async () => {
    loading.value = true
    await knowArchiveApi.imports({
        kb: formData.kb,
        scene: formData.scene,
        train_mode: formData.train_mode,
        chunk_size: formData.chunk_size,
        chunk_overlap: formData.chunk_overlap,
        separators: formData.separators,
        files: fileLists.value
    }).finally(() => {
        loading.value = false
    })

    feedback.msgSuccess('导入成功')
    emits('retreat')
}

watch(
    () => fileIndex.value,
    async (index: number) => {
        await resetPreview(index)
    }
)
</script>

<style scoped lang="scss">
.enter-from-box {
    padding: 12px 16px;
    margin: 12px;
    background-color: var(--el-color-light);
    border: 1px dashed var(--el-border-color-light);
    border-radius: 6px;
    :deep(.el-form-item__label) {
        font-weight: 400;
    }
    :deep(.el-textarea__inner) {
        padding: 10px 11px;
    }
}

.segment-type-box {
    padding: 12px;
    background-color: var(--el-color-light);
    border: 1px dashed var(--el-border-color-light);
    border-radius: 6px;
    .segment {
        padding: 10px 12px;
        cursor: pointer;
        background-color: var(--color-white);
        border: 1px solid var(--el-border-color-lighter);
        border-radius: 8px;
        :deep(.el-radio.el-radio--large) {
            height: auto;
            .el-radio__label {
                color: var(--el-text-color-regular);
            }
        }
    }
}

.parse-list-box {
    .parse-box {
        box-sizing: border-box;
        margin: 0 16px 12px;
        border: 1px solid var(--el-border-color-lighter);
        border-radius: 6px;
        .title {
            padding: 10px;
            font-size: 15px;
            font-weight: 700;
            border-bottom: 1px solid var(--el-border-color-lighter);
            .section {
                padding: 2px 10px;
                font-size: 13px;
                color: var(--el-color-primary);
                background-color: var(--el-bg-color-page);
                border-radius: 4px;
            }
        }
        .content {
            padding: 8px 15px;
            background-color: var(--el-bg-color-page);
        }
    }
}

.file-list-box {
    margin-top: 15px;
    li {
        display: flex;
        align-items: center;
        width: 100%;
        padding: 12px 14px;
        margin-bottom: 12px;
        cursor: pointer;
        border: 1px solid var(--el-border-color-light);
        border-radius: 8px;
        &.active {
            border-color: var(--el-color-primary);
        }
        .el-icon:hover {
            color: var(--el-color-error);
        }
        h3 {
            margin: 0 4px;
            font-size: 15px;
            color: var(--el-text-color-regular);
        }
    }
}
</style>
